# -*- coding: utf-8 -*-
import os
import uuid
from typing import List

from loguru import logger
from fastapi import Request, Form, File
from pydantic import BaseModel

from configs import UPLOAD_CLAUSE_FILE_DIR
from document_loader.clause_loader import ClauseLoader
from schemas.response_entity import JsonModel
from db.repository.user import db_get_user_group_ids, db_get_ugs_by_ids
from db.repository.clause import db_delete_clause_groups, db_create_clause_group,\
    db_get_clause_file_by_fileId, db_get_clause_file_by_filter, db_get_standards_by_filter,\
    db_update_clause_file_delete_state, db_create_clause_file, db_get_clause_file_by_filename,\
    db_delete_clauses, db_get_standard_by_clauseId, db_delete_clause, db_get_clause_for_user, db_update_clause_groups, \
    db_update_standard_clause_content, db_create_standard_clause, db_get_clauses_by_filters,\
    db_get_superadmin_clause_names, db_get_admin_clause_names, db_get_normal_user_clause_names
from utils.file_utils import write_2_file
from utils.hash_utils import cal_md5


class DeleteClauseFileEntity(BaseModel):
    token: str
    file_id: uuid.UUID


class DeleteClauseContentEntity(BaseModel):
    token: str
    clause_id: uuid.UUID


class UpdateClauseContentEntity(BaseModel):
    token: str
    clause_id: uuid.UUID
    clause_name: str = None
    institution: str = None
    clause_number: str = None
    original_text: str = None
    artificial_text: str = None
    area: str = None


class UpdateClauseGroupEntity(BaseModel):
	token: str
	file_id: uuid.UUID
	group_ids: List[int] = None


async def list_standard_clause(request: Request, token: str,
                               cargo: str = None, clause_name: str = None, institution: str = None,
                               clause_number: str = None, original_text: str = None, artificial_text: str = None,
                               area: str = None, page: int = 1, size: int = 10
                               ):
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg="用户token非法").to_response()

    # if not user.check_admin_role():
    #     return JsonModel(code=401, data=None, msg=f"用户无权限").to_response()

    user_groups = db_get_user_group_ids(user)
    is_admin = user.check_admin_role()
    total, clauses = db_get_clauses_by_filters(user_groups, is_admin, clause_name, institution, clause_number,
                                               original_text, artificial_text, area, cargo, page, size)

    return JsonModel(code=200, data={"total": total, "data": clauses}, msg=f"success").to_response()


async def list_standard_clause_name(request: Request, token: str):
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg="用户token非法").to_response()

    if user.check_superman_role():
        data = db_get_superadmin_clause_names()
        # 格式化超级管理员数据
        for item in data:
            item["groups"] = list(item["groups"].values())
    elif user.check_admin_role():
        data = db_get_admin_clause_names(user.id)
    else:
        data = db_get_normal_user_clause_names(user.id)
    return JsonModel(code=200, data=data, msg="success").to_response()


async def upload_standard_clause(
        request: Request,
        token: str = Form(),
        group_ids: List[int] = Form(),
        clause_name: str = Form(),
        file=File(...)
):
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg="用户token非法").to_response()

    if not user.check_admin_role():
        return JsonModel(code=401, data=None, msg=f"用户无权限").to_response()

    # if not user.check_permission("clause"):
    #     return JsonModel(code=402, data=None, msg=f"用户无操作权限").to_response()

    user_groups = db_get_user_group_ids(user)
    for group in group_ids:
        if group not in user_groups:
            return JsonModel(code=404, data=None, msg=f"用户组{group}不存在").to_response()

    # 计算文件的 MD5 值
    file_content = await file.read()
    file_name = cal_md5(file_content) + "." + file.filename.split('.')[-1]
    file_obj = db_get_clause_file_by_filename(user.id, file_name, clause_type=0)

    if file_obj and file_obj.is_delete is False:
        return JsonModel(code=400, data=None, msg=f"此文件已上传,请更换文件").to_response()

    # 保存文件到本地
    file_path = os.path.join(UPLOAD_CLAUSE_FILE_DIR, file_name)
    write_2_file(file_path, file_content)

    if file_obj:  # 逻辑删除时，更新
        file_obj = db_update_clause_file_delete_state(file_obj.id, delete=False)
    else:
        file_obj = db_create_clause_file(user_id=user.id, file_name=file_name, origin_name=file.filename, location=file_path,
                                    file_type=file.filename.split('.')[-1], file_size=file.size, clause_type=0)

    clause_loader = ClauseLoader()
    if clause_name is None:
        clause_name = file.filename.rpartition(".")[0]
    clause_result = clause_loader.standard_clause_parse(file_path, clause_name)
    for value in clause_result:
        new_standard_item = db_create_standard_clause(value, user.id, file_obj.id)

    for user_group_id in group_ids:
        db_create_clause_group(file_obj.id, user_group_id)

    return JsonModel(code=200, data={"id": str(file_obj.id)}, msg=f"解析文件:{file.filename}成功").to_response()


# 删除标准条款文件的文件
async def delete_standard_clause_file(request: Request, payload: DeleteClauseFileEntity):
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()

    if not user.check_admin_role():
        return JsonModel(code=401, data=None, msg=f"用户无权限").to_response()

    # if not user.check_permission("clause"):
    #     return JsonModel(code=402, data=None, msg=f"用户无操作权限").to_response()

    if user.check_superman_role():
        clause_file = db_get_clause_file_by_fileId(payload.file_id)
    else:
        clause_file = db_get_clause_file_by_filter(user.id, payload.file_id)

    if clause_file is None:
        return JsonModel(code=400, data=None, msg=f"条款文件不存在,请更换").to_response()
    clause_list_delete_state = db_delete_clauses(clause_file.id)
    clause_group_delete_state = db_delete_clause_groups(clause_file.id)
    db_update_clause_file_delete_state(clause_file.id, delete=True)
    return JsonModel(code=200, data=None, msg=f"删除标准文件及其条款成功").to_response()


# 删除标准条款文件的内容
async def delete_standard_clause_text(request: Request, payload: DeleteClauseContentEntity):
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()

    if not user.check_admin_role():
        return JsonModel(code=401, data=None, msg=f"用户无权限").to_response()

    # if not user.check_permission("clause"):
    #     return JsonModel(code=402, data=None, msg=f"用户无操作权限").to_response()

    if user.check_superman_role():
        clause = db_get_standard_by_clauseId(payload.clause_id)
    else:
        clause = db_get_standards_by_filter(user.id, payload.file_id)

    if clause is None:
        return JsonModel(code=400, data=None, msg=f"条款不存在,请更换条款").to_response()

    db_delete_clause(clause.id)
    return JsonModel(code=200, data=None, msg=f"删除条款成功").to_response()


async def update_standard_clause(request: Request, payload: UpdateClauseContentEntity):
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()
    if not user.check_admin_role():
        return JsonModel(code=401, data=None, msg=f"用户无权限").to_response()

    if user.check_superman_role():
        clause = db_get_standard_by_clauseId(payload.clause_id)
    else:
        clause = db_get_clause_for_user(payload.clause_id, user.id)

    if clause is None:
        return JsonModel(code=404, data=None, msg=f"条款不存在,请更换条款").to_response()

    update_data = {
        "clause_name": payload.clause_name,
        "institution": payload.institution,
        "clause_number": payload.clause_number,
        "original_text": payload.original_text,
        "artificial_text": payload.artificial_text,
        "area": payload.area
    }
    # 过滤掉None值
    valid_update_data = {k: v for k, v in update_data.items() if v is not None}

    # 更新条款
    updated_clause = db_update_standard_clause_content(clause, valid_update_data)
    return JsonModel(code=200, data=updated_clause.to_json(), msg=f"更新条款成功").to_response()


# 更新标准用户组
async def update_standard_clause_group(request: Request, payload: UpdateClauseGroupEntity):
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()
    if not user.check_admin_role():
        return JsonModel(code=401, data=None, msg=f"用户无权限").to_response()

    clause_file = db_get_clause_file_by_fileId(payload.file_id)
    if clause_file is None:
        return JsonModel(code=400, data=None, msg=f"文件不存在,请更换条款").to_response()

    if user.check_superman_role():
        accessible_groups = db_get_ugs_by_ids(payload.group_ids)
    else:
        accessible_groups = db_get_ugs_by_ids(payload.group_ids, user.id)

    if len(accessible_groups) != len(payload.group_ids):
        invalid_groups = set(payload.group_ids) - set(accessible_groups)
        return JsonModel(code=402, data=None, msg=f"用户无权访问以下组: {', '.join(map(str, invalid_groups))}").to_response()

    db_update_clause_groups(clause_file.id, payload.group_ids)
    return JsonModel(code=200, data=None, msg=f"更新条款成功").to_response()
